import UIKit

// 自定义组件类
public class DragAlertTitleView: UIView {
    
    // MARK: - 属性
    private var popupView: UIView?
    private var isPopupShowing = false
    private var containerView: UIView?
    private var shapeLayer: CAShapeLayer?
    
    // MARK: - 可配置属性
    public var buttonText: String = "拖拽我" {
        didSet {
            updateButtonText()
        }
    }
    
    public var popupText: String = "这是一个弹出视图\n箭头指向组件中心" {
        didSet {
            updatePopupText()
        }
    }
    
    public var buttonBackgroundColor: UIColor = .systemBlue {
        didSet {
            backgroundColor = buttonBackgroundColor
        }
    }
    
    public var popupBackgroundColor: UIColor = UIColor(red: 0.95, green: 0.95, blue: 0.97, alpha: 1.0) {
        didSet {
            updatePopupAppearance()
        }
    }
    
    // MARK: - UI组件
    private let buttonLabel = UILabel()
    private let contentLabel = UILabel()
    
    // MARK: - 初始化
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
        setupGestures()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupView()
        setupGestures()
    }
    
    // MARK: - 设置视图
    private func setupView() {
        backgroundColor = buttonBackgroundColor
        layer.cornerRadius = 12
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 2)
        layer.shadowOpacity = 0.3
        layer.shadowRadius = 4
        
        // 设置按钮标签
        buttonLabel.text = buttonText
        buttonLabel.textColor = .white
        buttonLabel.textAlignment = .center
        buttonLabel.font = UIFont.boldSystemFont(ofSize: 16)
        buttonLabel.numberOfLines = 0
        buttonLabel.translatesAutoresizingMaskIntoConstraints = false
        addSubview(buttonLabel)
        
        NSLayoutConstraint.activate([
            buttonLabel.topAnchor.constraint(equalTo: topAnchor, constant: 8),
            buttonLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
            buttonLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
            buttonLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8)
        ])
    }
    
    // MARK: - 更新按钮文本
    private func updateButtonText() {
        buttonLabel.text = buttonText
        // 根据文本内容调整按钮大小
        invalidateIntrinsicContentSize()
    }
    
    // MARK: - 更新弹窗文本
    private func updatePopupText() {
        contentLabel.text = popupText
        // 根据文本内容调整弹窗大小
        if isPopupShowing {
            updatePopupSize()
        }
    }
    
    // MARK: - 更新弹窗外观
    private func updatePopupAppearance() {
        if let shapeLayer = shapeLayer {
            shapeLayer.fillColor = popupBackgroundColor.cgColor
        }
    }
    
    // MARK: - 固有内容大小
    public  override var intrinsicContentSize: CGSize {
        let labelSize = buttonLabel.sizeThatFits(CGSize(width: 200, height: CGFloat.greatestFiniteMagnitude))
        return CGSize(width: labelSize.width + 24, height: labelSize.height + 16)
    }
    
    // MARK: - 手势设置
    private func setupGestures() {
        // 点击手势
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        addGestureRecognizer(tapGesture)
        
        // 拖拽手势
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
        addGestureRecognizer(panGesture)
    }
    
    // MARK: - 点击处理
    @objc private func handleTap() {
        if isPopupShowing {
            hidePopup()
        } else {
            showPopup()
        }
    }
    
    // MARK: - 拖拽处理
    @objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
        guard let superview = superview else { return }
        
        let translation = gesture.translation(in: superview)
        
        switch gesture.state {
        case .began, .changed:
            // 移动视图
            center = CGPoint(x: center.x + translation.x, y: center.y + translation.y)
            gesture.setTranslation(CGPoint.zero, in: superview)
            
            // 如果弹窗正在显示，更新弹窗位置
            if isPopupShowing {
                updatePopupPosition()
            }
            
        case .ended, .cancelled:
            // 确保视图不会移出父视图边界
            keepViewInBounds()
            
        default:
            break
        }
    }
    
    // MARK: - 显示弹窗
    private func showPopup() {
        guard let superview = superview else { return }
        
        // 创建弹窗（包含箭头）
        createPopupView()
        
        // 设置弹窗初始位置
        updatePopupPosition()
        
        // 立即更新形状
        if let containerView = containerView, let shapeLayer = shapeLayer {
            updatePopupShape(containerView: containerView, shapeLayer: shapeLayer)
        }
        
        // 显示动画
        popupView?.alpha = 0
        popupView?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
        
        UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: .curveEaseInOut) {
            self.popupView?.alpha = 1
            self.popupView?.transform = CGAffineTransform.identity
        }
        
        isPopupShowing = true
    }
    
    // MARK: - 隐藏弹窗
    private func hidePopup() {
        UIView.animate(withDuration: 0.2, animations: {
            self.popupView?.alpha = 0
            self.popupView?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
        }) { _ in
            self.popupView?.removeFromSuperview()
            self.popupView = nil
            self.containerView = nil
            self.shapeLayer = nil
            self.isPopupShowing = false
        }
    }
    
    // MARK: - 创建弹窗视图（包含箭头）
    private func createPopupView() {
        guard let superview = superview else { return }
        
        popupView = UIView()
        popupView?.backgroundColor = .clear
        superview.addSubview(popupView!)
        
        // 创建包含箭头和主体的容器
        containerView = UIView()
        containerView?.backgroundColor = .clear
        popupView?.addSubview(containerView!)
        
        // 创建形状图层来实现整体效果
        shapeLayer = CAShapeLayer()
        shapeLayer?.shadowColor = UIColor.black.cgColor
        shapeLayer?.shadowOffset = CGSize(width: 0, height: 4)
        shapeLayer?.shadowOpacity = 0.2
        shapeLayer?.shadowRadius = 8
        
        containerView?.layer.addSublayer(shapeLayer!)
        
        // 设置弹窗内容标签
        contentLabel.text = popupText
        contentLabel.numberOfLines = 0
        contentLabel.textAlignment = .center
        contentLabel.textColor = .darkGray
        contentLabel.font = UIFont.systemFont(ofSize: 14)
        contentLabel.translatesAutoresizingMaskIntoConstraints = false
        
        containerView?.addSubview(contentLabel)
        
        // 设置容器约束
        containerView?.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            containerView!.leadingAnchor.constraint(equalTo: popupView!.leadingAnchor),
            containerView!.trailingAnchor.constraint(equalTo: popupView!.trailingAnchor),
            containerView!.topAnchor.constraint(equalTo: popupView!.topAnchor),
            containerView!.bottomAnchor.constraint(equalTo: popupView!.bottomAnchor),
            
            contentLabel.topAnchor.constraint(equalTo: containerView!.topAnchor, constant: 12),
            contentLabel.leadingAnchor.constraint(equalTo: containerView!.leadingAnchor, constant: 16),
            contentLabel.trailingAnchor.constraint(equalTo: containerView!.trailingAnchor, constant: -16),
            contentLabel.bottomAnchor.constraint(equalTo: containerView!.bottomAnchor, constant: -20)
        ])
        
        // 根据内容调整弹窗大小
        updatePopupSize()
        
        // 强制立即布局
        popupView?.layoutIfNeeded()
        containerView?.layoutIfNeeded()
    }
    
    // MARK: - 更新弹窗大小
    private func updatePopupSize() {
        guard let popupView = popupView else { return }
        
        // 计算文本所需大小
        let maxWidth: CGFloat = 250
        let textSize = contentLabel.sizeThatFits(CGSize(width: maxWidth - 32, height: CGFloat.greatestFiniteMagnitude))
        
        // 计算弹窗大小（包含内边距和箭头空间）
        let popupWidth = min(maxWidth, textSize.width + 32)
        let popupHeight = textSize.height + 32 + 20 // 上下内边距 + 箭头空间
        
        popupView.frame.size = CGSize(width: popupWidth, height: popupHeight)
        
        // 更新位置
        if isPopupShowing {
            updatePopupPosition()
        }
    }
    
    // MARK: - 更新弹窗形状（包含箭头）
    private func updatePopupShape(containerView: UIView, shapeLayer: CAShapeLayer) {
        let path = UIBezierPath()
        let bounds = containerView.bounds
        let cornerRadius: CGFloat = 12
        let arrowWidth: CGFloat = 16
        let arrowHeight: CGFloat = 8
        
        // 从左上角开始绘制
        path.move(to: CGPoint(x: cornerRadius, y: 0))
        
        // 上边线
        path.addLine(to: CGPoint(x: bounds.width - cornerRadius, y: 0))
        path.addArc(withCenter: CGPoint(x: bounds.width - cornerRadius, y: cornerRadius),
                   radius: cornerRadius,
                   startAngle: -CGFloat.pi / 2,
                   endAngle: 0,
                   clockwise: true)
        
        // 右边线
        path.addLine(to: CGPoint(x: bounds.width, y: bounds.height - arrowHeight - cornerRadius))
        path.addArc(withCenter: CGPoint(x: bounds.width - cornerRadius, y: bounds.height - arrowHeight - cornerRadius),
                   radius: cornerRadius,
                   startAngle: 0,
                   endAngle: CGFloat.pi / 2,
                   clockwise: true)
        
        // 右下箭头
        let arrowCenterX = bounds.width / 2
        path.addLine(to: CGPoint(x: arrowCenterX + arrowWidth / 2, y: bounds.height - arrowHeight))
        path.addLine(to: CGPoint(x: arrowCenterX, y: bounds.height))
        path.addLine(to: CGPoint(x: arrowCenterX - arrowWidth / 2, y: bounds.height - arrowHeight))
        
        // 左下边线
        path.addLine(to: CGPoint(x: cornerRadius, y: bounds.height - arrowHeight))
        path.addArc(withCenter: CGPoint(x: cornerRadius, y: bounds.height - arrowHeight - cornerRadius),
                   radius: cornerRadius,
                   startAngle: CGFloat.pi / 2,
                   endAngle: CGFloat.pi,
                   clockwise: true)
        
        // 左边线
        path.addLine(to: CGPoint(x: 0, y: cornerRadius))
        path.addArc(withCenter: CGPoint(x: cornerRadius, y: cornerRadius),
                   radius: cornerRadius,
                   startAngle: CGFloat.pi,
                   endAngle: -CGFloat.pi / 2,
                   clockwise: true)
        
        path.close()
        
        shapeLayer.path = path.cgPath
        shapeLayer.fillColor = popupBackgroundColor.cgColor
        shapeLayer.strokeColor = UIColor.lightGray.cgColor
        shapeLayer.lineWidth = 0.5
        
        // 将内容标签置于最上层
        containerView.bringSubviewToFront(containerView.subviews.first!)
    }
    
    // MARK: - 更新弹窗位置
    private func updatePopupPosition() {
        guard let popupView = popupView, let superview = superview else { return }
        
        let popupWidth = popupView.frame.width
        let popupHeight = popupView.frame.height
        let spacing: CGFloat = 2
        
        // 计算弹窗位置（在组件上方）
        let popupY = frame.origin.y - popupHeight - spacing
        let popupX = center.x - popupWidth / 2
        
        // 确保弹窗不会超出屏幕边界
        var safeX = popupX
        var safeY = popupY
        
        // 检查左边界
        if safeX < 8 {
            safeX = 8
        }
        
        // 检查右边界
        if safeX + popupWidth > superview.bounds.width - 8 {
            safeX = superview.bounds.width - popupWidth - 8
        }
        
        // 检查上边界
        if safeY < 8 {
            safeY = frame.origin.y + frame.height + spacing
            // 重新创建弹窗以调整箭头方向
            if isPopupShowing {
                hidePopup()
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    self.showPopup()
                }
                return
            }
        }
        
        popupView.frame = CGRect(x: safeX, y: safeY, width: popupWidth, height: popupHeight)
        
        // 强制立即布局并更新形状
        popupView.layoutIfNeeded()
        if let containerView = containerView, let shapeLayer = shapeLayer {
            updatePopupShape(containerView: containerView, shapeLayer: shapeLayer)
        }
    }
    
    // MARK: - 确保视图在边界内
    private func keepViewInBounds() {
        guard let superview = superview else { return }
        
        var newFrame = frame
        
        // 检查左边界
        if newFrame.origin.x < 0 {
            newFrame.origin.x = 0
        }
        
        // 检查右边界
        if newFrame.origin.x + newFrame.width > superview.bounds.width {
            newFrame.origin.x = superview.bounds.width - newFrame.width
        }
        
        // 检查上边界
        if newFrame.origin.y < 0 {
            newFrame.origin.y = 0
        }
        
        // 检查下边界
        if newFrame.origin.y + newFrame.height > superview.bounds.height {
            newFrame.origin.y = superview.bounds.height - newFrame.height
        }
        
        UIView.animate(withDuration: 0.2) {
            self.frame = newFrame
        }
    }
}
